/*
 *  Copyright (c) 2018 Oray Inc. All rights reserverd.
 *  No Part of this file may be reproduced, stored
 *  in a retrieval system, or transmitted, in any form, or by any means,
 *  electronic, mechanical, photocopying, recording, or otherwise,
 *  without the prior consent of Oray Inc.
 *
 *  Author: qianwei
 *  Create on:  18-8-2 上午11:40
 *  FileName:SDCardUtils.java
 *
 *
 */

package com.bnq.control.desktop.utils;

import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;

import com.oray.commonutils.utils.BuildConfig;
import com.oray.commonutils.utils.CloseUtils;
import com.oray.commonutils.utils.LogUtil;
import com.oray.sunlogin.manager.bean.SDCardAttr;
import com.oray.sunlogin.manager.util.FileOperationUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by qianwei on 2018/8/2.
 */

public class SDCardUtils {

    /**
     * 錄像剩餘空間
     */
    private static final int AVAIL_SIZE_RECORDER = 20;


    /**
     * 是否有剩余自定义的空间大小
     *
     * @param sdPath
     * @return
     */
    public static boolean isAvailable(String sdPath) {
        return getAvailSize(sdPath) > AVAIL_SIZE_RECORDER;
    }

    /**
     * 返回sd路径，如果有外置sd卡，则先返回外置路径，否则返回内置sd卡路径
     *
     * @return
     */
    public static SDCardAttr getSdCardPath(Context context) {
        SDCardAttr sdEntity = new SDCardAttr();
        //适配安卓Q
        if (BuildConfig.hasQ()) {
            sdEntity.sdPath = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
            sdEntity.isBuildVersionQ = true;
            return sdEntity;
        }
        String sd_default = Environment.getExternalStorageDirectory().getAbsolutePath();
        List<String> extSDCardPaths = getExtSDCardPaths();
        if (null != extSDCardPaths && extSDCardPaths.size() > 0) {
            for (String path : extSDCardPaths) {
                if (path.toUpperCase().contains("sd".toUpperCase())) {
                    sd_default = path;
                    break;
                }
            }
        } else {
            String extSDCardPath = getExtSDCardPath();
            if (Build.VERSION.SDK_INT >= 23 && !TextUtils.isEmpty(extSDCardPath)) {
                sd_default = extSDCardPath;
            }
        }
        if (!sd_default.equals(Environment.getExternalStorageDirectory().getAbsolutePath())) {
            String sd_cache = sd_default;

	    	/*小米4.2的手机内部存储是sdcard1,插入sd卡，Environment.getExternalStorageDirectory()会变成外置sd卡的路径sdcard0,
                所以针对小米系统4.2特别处理
	    	 */
            if (Build.VERSION.SDK_INT < 18 && Build.BRAND.toUpperCase().equals("Xiaomi".toUpperCase())) {
                sd_default = Environment.getExternalStorageDirectory().getAbsolutePath();
            }
            sdEntity.isOutSD = true;
            if (!isAvailable(sd_default)) {//如果外置sd没有空间，就返回内置sd卡
                if (Build.VERSION.SDK_INT < 18 && Build.BRAND.toUpperCase().equals("Xiaomi".toUpperCase())) {
                    sd_default = sd_cache;
                } else {
                    sd_default = Environment.getExternalStorageDirectory().getAbsolutePath();
                }
                sdEntity.isOutSD = false;
            }
        } else {
            sdEntity.isOutSD = false;
        }
        sdEntity.sdPath = sd_default;
        if (sdEntity.isOutSD && !canSaveOutSDCard(sd_default)) {//如果有外置sd卡但是不能存儲，則返回內置sd卡
            sdEntity.sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
            sdEntity.isOutSD = false;
        }
        return sdEntity;
    }

    public static boolean canSaveOutSDCard(String path) {
        try {
            File file = new File(path, File.separator + FileOperationUtils.getParentFileName()
                    + File.separator + "temp" + File.separator);
            if (!file.exists()) {
                return file.mkdirs();
            } else {
                return file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取外置sd卡集合
     *
     * @return
     */
    public static List<String> getExtSDCardPaths() {
        List<String> paths = new ArrayList<String>();
        String extFileStatus = Environment.getExternalStorageState();
        File extFile = Environment.getExternalStorageDirectory();
        if (extFileStatus.endsWith(Environment.MEDIA_UNMOUNTED)
                && extFile.exists() && extFile.isDirectory()
                && extFile.canWrite()) {
            paths.add(extFile.getAbsolutePath());
        }
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            // obtain executed result of command line code of 'mount', to judge
            // whether tfCard exists by the result
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec("mount");
            is = process.getInputStream();
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);
            String line;
            int mountPathIndex = 1;
            while ((line = br.readLine()) != null) {
                // format of sdcard file system: vfat/fuse
                if ((!line.contains("fat") && !line.contains("fuse") && !line
                        .contains("storage"))
                        || line.contains("secure")
                        || line.contains("asec")
                        || line.contains("firmware")
                        || line.contains("shell")
                        || line.contains("obb")
                        || line.contains("legacy") || line.contains("data")) {
                    continue;
                }
                String[] parts = line.split(" ");
                int length = parts.length;
                if (mountPathIndex >= length) {
                    continue;
                }
                String mountPath = parts[mountPathIndex];
                if (!mountPath.contains("/") || mountPath.contains("data") || mountPath.contains("Data")) {
                    continue;
                }
                File mountRoot = new File(mountPath);
                if (!mountRoot.exists() || !mountRoot.isDirectory()
                        || !mountRoot.canWrite()) {
                    continue;
                }
                boolean equalsToPrimarySD = mountPath.equals(extFile
                        .getAbsolutePath());
                if (equalsToPrimarySD) {
                    continue;
                }
                paths.add(mountPath);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            CloseUtils.closeQuietly(is);
            CloseUtils.closeQuietly(isr);
            CloseUtils.closeQuietly(br);
        }
        return paths;
    }

    public static String getExtSDCardPath() {

        String exPath = "";
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec("ls /storage");
            is = process.getInputStream();
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);
            String line;
            String s = "";
            while ((line = br.readLine()) != null) {
                s = line + ",";
                if (!TextUtils.isEmpty(line) && !line.toUpperCase().contains("emulated".toUpperCase())
                        && !line.toUpperCase().contains("self".toUpperCase())) {
                    exPath = "/storage/" + line;
                }
            }
            LogUtil.i("storage", s);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            CloseUtils.closeQuietly(is);
            CloseUtils.closeQuietly(isr);
            CloseUtils.closeQuietly(br);
        }
        return exPath;
    }

    public static long getAvailSize(String path) {
        StatFs stat = new StatFs(path);
        long blockSize = stat.getBlockSize();   // 获得一个扇区的大小
        long availableBlocks = stat.getAvailableBlocks();   // 获得可用的扇区数量
        return (availableBlocks * blockSize) / 1024 / 1024;
    }

}
